package com.yaodian100.ec.order.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.common.dao.ObjectDao;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.DomainService;
import com.yaodian100.core.common.service.impl.DomainServiceImpl;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.JspUtil;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.core.logger.service.LogService;
import com.yaodian100.core.mail.entity.Mail;
import com.yaodian100.core.mail.service.MailService;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.sms.service.SmsService;
import com.yaodian100.core.template.service.TemplateService;
import com.yaodian100.crm.cs.service.CsService;
import com.yaodian100.ec.cobranding.entity.DPNStore;
import com.yaodian100.ec.cobranding.service.DPNService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.common.EnvParameters;
import com.yaodian100.ec.delivery.entity.ViewDeliveryRule;
import com.yaodian100.ec.delivery.service.DeliveryRuleService;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.entity.VirtualBalance;
import com.yaodian100.ec.member.entity.VirtualBalance.VirtualBalancePayType;
import com.yaodian100.ec.member.entity.VirtualBalance.VirtualBalanceType;
import com.yaodian100.ec.member.service.AddessService;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.order.entity.OrderProduct;
import com.yaodian100.ec.order.entity.OrderProductDetail;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.OrderModifyService;
import com.yaodian100.ec.order.service.OrderService;

public class OrderModifyServiceImpl extends DomainServiceImpl<Orders> implements OrderModifyService, InitializingBean {
	private ObjectDao<OrderProduct> orderProductDao;
	private ObjectDao<OrderProductDetail> orderProductDetailDao;
	@Resource
	private MemberService memberService;
	@Resource
	private SmsService smsService;
	@Resource
	private MailService mailService;
	@Resource
	private TemplateService velocityService;
	@Resource
	private EnvParameters envParameters;
	@Resource
	private DomainService<Menu> menuService;
	private Menu paymentTpMenu;
	@Resource
	private LogService logService;
	@Autowired
	private AddessService addressService;
	@Autowired
	private DPNService dpnService;
	@Autowired
	private DeliveryRuleService deliveryRuleService;
	@Autowired
	private OrderService orderService;
	@Resource
	private CsService csService;

	public void setOrderProductDao(ObjectDao<OrderProduct> orderProductDao) {
		this.orderProductDao = orderProductDao;
	}

	public void setOrderProductDetailDao(ObjectDao<OrderProductDetail> orderProductDetailDao) {
		this.orderProductDetailDao = orderProductDetailDao;
	}

	@Transactional(readOnly = false)
	public ArrayList<String> updateOrderPaymentTp(String orderId, String paytype, boolean midendUse) throws Exception {
		return updateOrderPaymentTp(orderId, paytype, midendUse, "", null);
	}

	@Transactional(readOnly = false)
	public ArrayList<String> updateOrderPaymentTp(String orderId, String paytype, boolean midendUse, String memberId,
			String allowSplit) throws Exception {
		ArrayList<String> orderChangeInfo = new ArrayList();
		Orders order = this.get(orderId);
		if (null == order) {
			return orderChangeInfo;
		} else {
			// TODO_jeffma COD_FEE 拆单目前不允许
			BigDecimal joinMustPayChange = BigDecimal.ZERO;
			List<Orders> orderList = new ArrayList();
			for (String o : StringUtils.split(order.getJoinOrders(), ",")) {
				if (!o.equals(order.getOrderId())) {
					order = this.get(o);
				}
				orderList.add(order);
				Orders oldOrder = new Orders();
				if ((!memberId.equals(order.getMemberId())) && midendUse == false) {
					throw new CoreException(OrderModifyService.ERROR_ORDER_ORDER_NOT_EXISTS);
				}
				try {
					oldOrder = (Orders) BeanUtils.cloneBean(order);
				} catch (Exception e) {
					logger.error("updateOrderPaymentTp_cloneBean Error:{}", order.getOrderId());
				}
				// 貨到付款
				if ("30".equals(order.getPaymentTp()) || "60".equals(order.getPaymentTp())) {// 貨到付款
					if ("00".equals(order.getOrderSt())) {// 訂單審核中
						order.setPaymentTp(paytype);
						if (StringUtils.isNotBlank(allowSplit) && "Y".equals(allowSplit)) {
							order.setAllowSplit("Y");
						}
						// 修改為網上支付
						if ("50".equals(paytype) || "10".equals(paytype) || "20".equals(paytype) || "70".equals(paytype)) {
							order.setOrderSt("10");// 等待付款
							order.setMustPay(order.getMustPay().subtract(oldOrder.getCodFee()));
							order.setCodFee(BigDecimal.ZERO);
							joinMustPayChange = joinMustPayChange.subtract(oldOrder.getCodFee());
							orderChangeInfo.add("codFee");
							// 转为网上支付/银行or邮局转帐之方式后，需于该支付方式之付款期限内付款完成，否則視同逾期付款支"取消訂單"。
							// 付款期限：線上支付: 24hr; 匯款/ATM/郵區 : 7x24 hr
							if (!(StringUtils.defaultString(order.getMemo()).length() > 0 && StringUtils.defaultString(
									order.getMemo()).indexOf("异常") >= 0)) {
								if ("10".equals(paytype) || "20".equals(paytype)) {
									Date dead7 = DateUtil.getTodayAddDays(7).getTime();
									dead7 = DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead7);
									order.setDeadline(dead7);
								} else if ("50".equals(paytype) || "70".equals(paytype)) {
									Date dead1 = DateUtil.getTodayAddDays(1).getTime();
									dead1 = DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead1);
									order.setDeadline(dead1);
								} else {
									order.setDeadline(null);
								}
							}
						}
						// 修改為帳戶餘額
						BigDecimal orginOrderMustPay = order.getMustPay();// 原始應付餘額
						if ("40".equals(paytype)) {// 帳戶餘額
							Member member = memberService.get(order.getMemberId());
							if (member.getBalance().getVirtualBalance().compareTo(order.getMustPay()) > 0) {
								order.setOrderSt("20");// 20 等待配貨
								order.setPaymentSt("10");// 10完成付款
								order.setMyWallet(order.getMustPay().add(order.getMyWallet()).subtract(order.getCodFee()));
								joinMustPayChange = joinMustPayChange.subtract(oldOrder.getCodFee());
								orderChangeInfo.add("myWallet");
								order.setMustPay(BigDecimal.ZERO);
								order.setCodFee(BigDecimal.ZERO);
								orderChangeInfo.add("codFee");
								Date currentDate = new Date();
								order.setSyncDt(currentDate);
								order.setPaymentDt(currentDate);
								// 扣除帳戶餘額
								if (orginOrderMustPay.floatValue() > 0.0f) {
									VirtualBalance vb = new VirtualBalance();
									vb.setMemberId(order.getMemberId());
									vb.setTrxDate(new Date());
									vb.setTrxType(VirtualBalanceType.EC_ORDER_MAIN.name());
									vb.setTrxAmount(orginOrderMustPay.negate());
									vb.setDescription("支付至订单：<a href=\"" + ServerValue.getFrontContextPath()
											+ "/member/order/page.do?page=detail&orderId=" + order.getOrderId() + "\">" + order.getOrderId()
											+ "</a>");
									vb.setTrxTypeId(order.getOrderId());
									vb.setType(VirtualBalancePayType.VirtualBalance.getValue());
									vb = memberService.saveOrUpdateVirtualBalance(vb);
									logger.info("vb.getTrxAmount():{}", vb.getTrxAmount());
								}
							} else {
								throw new CoreException(OrderModifyService.ERROR_ORDER_MUSTPAY_BIGGER_VIRTUALBALANCE);
							}
						}
					} else {
						throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y3060N00);
					}
				}
				// 网上支付,信用卡單期
				if ("50".equals(order.getPaymentTp()) || "70".equals(order.getPaymentTp())) {
					if ("10".equals(order.getOrderSt())) {// 等待付款
						order.setPaymentTp(paytype);
						// 修改為帳戶餘額
						BigDecimal orginOrderMustPay = order.getMustPay();// 原始應付餘額
						if ("40".equals(paytype)) {// 帳戶餘額
							Member member = memberService.get(order.getMemberId());
							if (member.getBalance().getVirtualBalance().compareTo(order.getMustPay()) > 0) {
								order.setOrderSt("20");// 20 等待配貨
								order.setPaymentSt("10");// 10完成付款
								order.setMyWallet(order.getMustPay().add(order.getMyWallet()));
								orderChangeInfo.add("myWallet");
								order.setMustPay(BigDecimal.ZERO);
								joinMustPayChange = joinMustPayChange.subtract(order.getMyWallet());
								Date currentDate = new Date();
								order.setSyncDt(currentDate);
								order.setPaymentDt(currentDate);
								// 扣除帳戶餘額
								if (orginOrderMustPay.floatValue() > 0.0f) {
									VirtualBalance vb = new VirtualBalance();
									vb.setMemberId(order.getMemberId());
									vb.setTrxDate(new Date());
									vb.setTrxType(VirtualBalanceType.EC_ORDER_MAIN.name());
									vb.setTrxAmount(orginOrderMustPay.negate());
									vb.setDescription("支付至订单：<a href=\"" + ServerValue.getFrontContextPath()
											+ "/member/order/page.do?page=detail&orderId=" + order.getOrderId() + "\">" + order.getOrderId()
											+ "</a>");
									vb.setTrxTypeId(order.getOrderId());
									vb.setType(VirtualBalancePayType.VirtualBalance.getValue());
									vb = memberService.saveOrUpdateVirtualBalance(vb);
								}
							} else {
								logger.info("xxxxxxxxxxxxxxxxxxxxxxxOrderModifyService.ERROR_ORDER_MUSTPAY_BIGGER_VIRTUALBALANCE");
								throw new CoreException(OrderModifyService.ERROR_ORDER_MUSTPAY_BIGGER_VIRTUALBALANCE);
							}
						}
						// 修改為邮局/银行
						if (!(StringUtils.defaultString(order.getMemo()).length() > 0 && StringUtils.defaultString(order.getMemo())
								.indexOf("异常") >= 0)) {
							if ("10".equals(paytype) || "20".equals(paytype)) {
								order.setOrderSt("10");// 等待付款
								// 转为网上支付/银行or邮局转帐之方式后，需于该支付方式之付款期限内付款完成，否則視同逾期付款支"取消訂單"。
								// 付款期限：線上支付: 72hr; 匯款/ATM/郵區 : 7x24 hr
								Date dead7 = DateUtil.getTodayAddDays(7).getTime();
								dead7 = DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead7);
								order.setDeadline(dead7);
							}
						}
						// 修改為货到付款
						if ("30".equals(paytype) || "60".equals(paytype)) {
							order.setAllowSplit("N"); // 货到付款不允许拆单
							ViewDeliveryRule viewDeliveryRule = deliveryRuleService.canUseCodByOrderId(order.getOrderId());
							// order.setDeadline(null);
							if (null != viewDeliveryRule) {
								if ("30".equals(paytype) && "Y".equals(viewDeliveryRule.getIsCod())) {
									if (orderService.verifyOrder("365", order.getMemberId(), "90") && order.getMustPay().intValue() > 200
											&& "off".equals(ServerValue.getBlockOrderPaymentType())) {
										order.setOrderSt("00");// 訂單審核中
										csService.createPayByProductArrive(order.getMemberId(), order.getOrderId(), "");
									} else {
										order.setOrderSt("20");// 20 等待配貨
										Date currentDate = DateUtil.getCurrentTime();
										order.setSyncDt(currentDate);// 同步用
									}
									order.setCodFee(addressService.getCodFee());
									order.setMustPay(order.getMustPay().add(order.getCodFee()));
									joinMustPayChange = joinMustPayChange.add(order.getCodFee());
									orderChangeInfo.add("codFee");
								} else if ("60".equals(paytype) && "Y".equals(viewDeliveryRule.getIsPos())) {
									if (orderService.verifyOrder("365", order.getMemberId(), "90") && order.getMustPay().intValue() > 200
											&& "off".equals(ServerValue.getBlockOrderPaymentType())) {
										order.setOrderSt("00");// 訂單審核中
										csService.createPayByProductArrive(order.getMemberId(), order.getOrderId(), "");
									} else {
										order.setOrderSt("20");// 20 等待配貨
										Date currentDate = DateUtil.getCurrentTime();
										order.setSyncDt(currentDate);// 同步用
									}
									order.setCodFee(addressService.getCodFee());
									order.setMustPay(order.getMustPay().add(order.getCodFee()));
									joinMustPayChange = joinMustPayChange.add(order.getCodFee());
									orderChangeInfo.add("codFee");

								} else {
									throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
								}
							} else {
								throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
							}
						}
					} else {
						throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
					}
				}
				if (midendUse) {
					if ("10".equals(order.getPaymentTp()) || "20".equals(order.getPaymentTp())) {
						if ("10".equals(order.getOrderSt())) {// 等待付款
							order.setPaymentTp(paytype);
							// 修改為帳戶餘額
							BigDecimal orginOrderMustPay = order.getMustPay();// 原始應付餘額
							if ("40".equals(paytype)) {// 帳戶餘額
								Member member = memberService.get(order.getMemberId());
								if (member.getBalance().getVirtualBalance().compareTo(order.getMustPay()) > 0) {
									order.setOrderSt("20");// 20 等待配貨
									order.setPaymentSt("10");// 10完成付款
									order.setMyWallet(order.getMustPay().add(order.getMyWallet()));
									orderChangeInfo.add("myWallet");
									order.setMustPay(BigDecimal.ZERO);
									joinMustPayChange = joinMustPayChange.subtract(order.getMyWallet());
									Date currentDate = new Date();
									order.setSyncDt(currentDate);
									order.setPaymentDt(currentDate);
									// 扣除帳戶餘額
									if (orginOrderMustPay.floatValue() > 0.0f) {
										VirtualBalance vb = new VirtualBalance();
										vb.setMemberId(order.getMemberId());
										vb.setTrxDate(new Date());
										vb.setTrxType(VirtualBalanceType.EC_ORDER_MAIN.name());
										vb.setTrxAmount(orginOrderMustPay.negate());
										vb.setDescription("支付至订单：<a href=\"" + ServerValue.getFrontContextPath()
												+ "/member/order/page.do?page=detail&orderId=" + order.getOrderId() + "\">"
												+ order.getOrderId() + "</a>");
										vb.setTrxTypeId(order.getOrderId());
										vb.setType(VirtualBalancePayType.VirtualBalance.getValue());
										vb = memberService.saveOrUpdateVirtualBalance(vb);
									}
								} else {
									throw new CoreException(OrderModifyService.ERROR_ORDER_MUSTPAY_BIGGER_VIRTUALBALANCE);
								}
							}
							// 修改為網上支付
							if ("50".equals(paytype) || "10".equals(paytype) || "20".equals(paytype) || "70".equals(paytype)) {
								order.setOrderSt("10");// 等待付款
								order.setMustPay(order.getMustPay().subtract(order.getCodFee()));
								joinMustPayChange = joinMustPayChange.subtract(order.getCodFee());
								order.setCodFee(BigDecimal.ZERO);// 要放在最後

								// 转为网上支付/银行or邮局转帐之方式后，需于该支付方式之付款期限内付款完成，否則視同逾期付款支"取消訂單"。
								// 付款期限：線上支付: 24hr; 匯款/ATM/郵區 : 7x24 hr
								if (!(StringUtils.defaultString(order.getMemo()).length() > 0 && StringUtils.defaultString(
										order.getMemo()).indexOf("异常") >= 0)) {
									if ("10".equals(paytype) || "20".equals(paytype) || "30".equals(paytype) || "60".equals(paytype)) {
										Date dead7 = DateUtil.getTodayAddDays(7).getTime();
										dead7 = DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead7);
										order.setDeadline(dead7);
									} else {
										Date dead1 = DateUtil.getTodayAddDays(1).getTime();
										dead1 = DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead1);
										order.setDeadline(dead1);// ?需要每個都重置deadline?
									}
								}
							}
							// 修改為货到付款
							if ("30".equals(paytype) || "60".equals(paytype)) {
								order.setAllowSplit("N"); // 货到付款不允许拆单
								// order.setDeadline(null);
								ViewDeliveryRule viewDeliveryRule = deliveryRuleService.canUseCodByOrderId(order.getOrderId());
								if (null != viewDeliveryRule) {
									if ("30".equals(paytype) && "Y".equals(viewDeliveryRule.getIsCod())) {
										if (orderService.verifyOrder("365", order.getMemberId(), "90")
												&& order.getMustPay().intValue() > 200 && "off".equals(ServerValue.getBlockOrderPaymentType())) {
											order.setOrderSt("00");// 訂單審核中
										} else {
											order.setOrderSt("20");// 20 等待配貨
											Date currentDate = DateUtil.getCurrentTime();
											order.setSyncDt(currentDate);// 同步用
										}
										order.setCodFee(addressService.getCodFee());// 要放在最後
										order.setMustPay(order.getMustPay().add(order.getCodFee()));
										joinMustPayChange = joinMustPayChange.add(order.getCodFee());
									} else if ("60".equals(paytype) && "Y".equals(viewDeliveryRule.getIsPos())) {
										if (orderService.verifyOrder("365", order.getMemberId(), "90")
												&& order.getMustPay().intValue() > 200 && "off".equals(ServerValue.getBlockOrderPaymentType())) {
											order.setOrderSt("00");// 訂單審核中
										} else {
											order.setOrderSt("20");// 20 等待配貨
											Date currentDate = DateUtil.getCurrentTime();
											order.setSyncDt(currentDate);// 同步用
										}
										order.setCodFee(addressService.getCodFee());// 要放在最後
										order.setMustPay(order.getMustPay().add(order.getCodFee()));
										joinMustPayChange = joinMustPayChange.add(order.getCodFee());
									} else {
										throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
									}
								} else {
									throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
								}
							}
						} else {
							throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_PAYTYPE_Y50N10);
						}

						try {
							if (!oldOrder.getPaymentTp().equals(paytype)) {
								if (order.getOrderSt().equals("00") || order.getOrderSt().equals("10")) {
									order.setSyncDt(null);
								}
								// 发出修改订单通知信(手机/邮箱会员）&手机会员发短信
								sendOrderModifyMail("orderModifyPayType", order);
								orderChangeInfo.add("paymentTp");
								logService.save(this.getClass().getName(), "chgPaymentTp", oldOrder);
								if (order.getOrderSt().equals("00")) {// 00 訂單審核中-建立工單
									csService.createPayByProductArrive(order.getMemberId(), order.getOrderId(), "");
								}
							}
						} catch (Exception e) {
							logger.info("updateOrderPaymentTp_exception:{}");
						}
					}
				}
			}
			for (Orders o : orderList) {
				o.setJoinMustPay(o.getJoinMustPay().add(joinMustPayChange));
				o = orderService.calcOrderProduct(o);// 重新計算訂單各項商品的攤提比例
				this.update(o);
			}
			memberService.updateOrder2PayBalance(order.getMemberId());// 更新會員帳戶資料

			return orderChangeInfo;
		}
	}

	@Transactional(readOnly = false)
	public void sendOrderModifyMail(String velocityTemplate, Orders order) throws CoreException {
		try {
			Member member = memberService.get(order.getMemberId());
			if (member.getMobile() != null && member.getMobile().length() > 0) {
				String msg = "";
				// 修改支付方式
				if ("orderModifyPayType".equals(velocityTemplate)) {
					if ("50".equals(order.getPaymentTp()) || "10".equals(order.getPaymentTp())
							|| "20".equals(order.getPaymentTp())) {// 修改為網上支付
						msg = "您已变更订单" + order.getOrderId() + "支付方式，请查询订单并依指示付款，我们将尽快发货。如有疑问请致电耀点100：4001-168-100。";
					}
					if ("40".equals(order.getPaymentTp())) {// 修改為帳戶餘額
						msg = "耀点100会员您好，您已变更订单" + order.getOrderId() + "支付方式为账户余额，并已全额付清，商品将于近日发出。";
					}
					if ("30".equals(order.getPaymentTp()) || "60".equals(order.getPaymentTp())) {// 修改為货到付款
						msg = "您已变更耀点100订单" + order.getOrderId() + "的支付方式为货到付款，商品将于近日发出，请在收货时向送货员支付货款共计"
								+ JspUtil.currency(order.getMustPay()) + "元。";
					}
				}
				// 修改出货人信息
				if ("orderModifyAddress".equals(velocityTemplate)) {
					msg = "您已变更订单" + order.getOrderId() + "收货人信息，您可进入耀点100网站查询变更后之订单内容，如非本人操作，请致电4001-168-100。";
				}
				smsService.sendSms(member.getMobile(), msg, order.getOrderId());
			}

			Map<String, Object> contentMap = new HashMap<String, Object>();
			CommonCriteria commonCriteria = new CommonCriteria();
			commonCriteria.addEq("orderId", order.getOrderId());

			contentMap.put("order", order);
			contentMap.put("deadline", FastDateFormat.getInstance(EcConstant.PATTERN_TIMESTAMP).format(order.getDeadline()));
			contentMap.put("orderDt", FastDateFormat.getInstance(EcConstant.PATTERN_TIMESTAMP).format(order.getOrderDt()));
			CommonCriteria crit = new CommonCriteria();
			crit.addEq("orderId", order.getOrderId());
			contentMap.put("paymentTpMenu", paymentTpMenu);
			contentMap.put("customerFax", ServerValue.getCustomerFax());
			contentMap.put("customerTel", ServerValue.getCustomerTel());
			contentMap.put("contextpath", ServerValue.getFrontContextPath());
			contentMap.put("basehref", "http://" + order.getDomainSrc());
			Mail mail = velocityService.formatToMail(velocityTemplate, contentMap);
			mail.setTo(member.getSendEmail());
			mail.setFrom(envParameters.getEmailFromSystem());
			mail.setSubject("您已经修改订单" + order.getOrderId());
			mailService.save(mail);
		} catch (Exception e) {
			logger.error("err:" + e.getMessage());
		}
	}

	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}

	public void setMailService(MailService mailService) {
		this.mailService = mailService;
	}

	public void setVelocityService(TemplateService velocityService) {
		this.velocityService = velocityService;
	}

	public EnvParameters getEnvParameters() {
		return envParameters;
	}

	public void setEnvParameters(EnvParameters envParameters) {
		this.envParameters = envParameters;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (paymentTpMenu == null) {
			paymentTpMenu = menuService.get("Order.PaymentTp");
		}
	}

	public void setPaymentTpMenu(Menu paymentTpMenu) {
		this.paymentTpMenu = paymentTpMenu;
	}

	public void setSmsService(SmsService smsService) {
		this.smsService = smsService;
	}

	public void setAddressService(AddessService addressService) {
		this.addressService = addressService;
	}

	@Transactional(readOnly = false)
	public ArrayList<String> updateOrderAddres(String orderId, Map<String, Object> attrs) throws Exception {
		ArrayList<String> orderChangeInfo = new ArrayList();
		Orders order = this.get(orderId);
		if (null == order) {
			return orderChangeInfo;
		} else {
			Orders oldOrder = new Orders();
			try {
				oldOrder = (Orders) BeanUtils.cloneBean(order);
			} catch (Exception e) {
				logger.error("updateOrderAddres_cloneBean Error:{}", order.getOrderId());
			}
			if ("30".equals(order.getPaymentTp()) || "60".equals(order.getPaymentTp())) {// 貨到付款
				if ("00".equals(order.getOrderSt())) {// 訂單審核中
					compareReceiverAddress(order, oldOrder, attrs, orderChangeInfo);
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
				} else if ("20".equals(order.getOrderSt())) {// 等待配货
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
					if (attrs.containsKey("midend") && order.isSync() == false) {// 貨到付款，只有中台在等待配货且尚未同步到後台時可以修改地址
						compareReceiverAddress(order, oldOrder, attrs, orderChangeInfo);
					}
				} else {
					throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y3060N0020);
				}
			}

			if ("50".equals(order.getPaymentTp()) || "70".equals(order.getPaymentTp()) || "80".equals(order.getPaymentTp())) {// 網上支付//信用卡分期//信用卡單期
				if ("10".equals(order.getOrderSt())) {// 等待付款
					if ("30".equals(order.getReceiverTp())) {// 達芙妮訂單
						if (!attrs.get("storeId").toString().equals(oldOrder.getStoreId())) {
							if (StringUtils.isNotBlank(attrs.get("storeId").toString())) {
								order.setReceiverTp("30");// 表示達芙妮門店取貨
								CommonCriteria crit = new CommonCriteria();
								crit.addEq("storeId", attrs.get("storeId").toString());
								if (dpnService.getDPNStoretList(crit).size() > 0) {
									DPNStore dpnstore = dpnService.getDPNStoretList(crit).get(0);
									order.setReceiverZip(dpnstore.getStoreZip());
									order.setReceiverAddr(dpnstore.getStoreAddress() + "(" + dpnstore.getStoreName() + "-"
											+ dpnstore.getStoreType() + ")");
									order.setReceiverArea(dpnstore.getStoreArea());
									order.setReceiverCity(dpnstore.getStoreCity());
									order.setStoreId(attrs.get("storeId").toString());
								}
								orderChangeInfo.add("receiverAddr");
							}
						}
						compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
						compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
					} else {// 其它訂單
						compareReceiverAddress(order, oldOrder, attrs, orderChangeInfo);
						compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
						compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
					}
				} else if ("20".equals(order.getOrderSt())) {// 等待配貨
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
				} else if (!"www.yaodian100.com".equals(order.getDomainSrc())
						&& ("00".equals(order.getOrderSt()) || "05".equals(order.getOrderSt()))) {// 不是主站的，订单状态 '00'或'05' 允许修改地址
					if ((!attrs.get("zipCode").toString().equals(oldOrder.getReceiverZip()))
							|| (!attrs.get("province").toString().equals(oldOrder.getReceiverProvince()))
							|| (!attrs.get("city").toString().equals(oldOrder.getReceiverCity()))
							|| (!attrs.get("district").toString().equals(oldOrder.getReceiverArea()))
							|| (!attrs.get("addr").toString().equals(oldOrder.getReceiverAddr()))) {
						order.setReceiverZip(attrs.get("zipCode").toString());
						order.setReceiverProvince(attrs.get("province").toString());
						order.setReceiverCity(attrs.get("city").toString());
						order.setReceiverArea(attrs.get("district").toString());
						order.setReceiverAddr(attrs.get("addr").toString());
						orderChangeInfo.add("receiverAddr");
					}
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
				} else {
					throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y50N1020);
				}
			}
			if ("40".equals(order.getPaymentTp()) && order.getMustPay().intValue() == 0) {// 帳戶餘額
				if ("20".equals(order.getOrderSt())) {// 等待配貨
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
				} else {
					throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y40N20);
				}
			}
			if ("10".equals(order.getPaymentTp()) || "20".equals(order.getPaymentTp())) {// 銀行or郵局轉帳
				if ("10".equals(order.getOrderSt()) || "20".equals(order.getOrderSt())) {// 10等待付款，20等待配貨
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
					if (attrs.containsKey("midend")) {// 銀行or郵局轉帳，只有中台在等待付款時可以修改地址
						if ("10".equals(order.getOrderSt())) {
							if ("30".equals(order.getReceiverTp())) {// 達芙妮訂單
								if (!attrs.get("storeId").toString().equals(oldOrder.getStoreId())) {
									if (StringUtils.isNotBlank(attrs.get("storeId").toString())) {
										order.setReceiverTp("30");// 表示達芙妮門店取貨
										CommonCriteria crit = new CommonCriteria();
										crit.addEq("storeId", attrs.get("storeId").toString());
										if (dpnService.getDPNStoretList(crit).size() > 0) {
											DPNStore dpnstore = dpnService.getDPNStoretList(crit).get(0);
											order.setReceiverZip(dpnstore.getStoreZip());
											order.setReceiverAddr(dpnstore.getStoreAddress() + "(" + dpnstore.getStoreName() + "-"
													+ dpnstore.getStoreType() + ")");
											order.setReceiverArea(dpnstore.getStoreArea());
											order.setReceiverCity(dpnstore.getStoreCity());
											order.setStoreId(attrs.get("storeId").toString());
										}
										orderChangeInfo.add("receiverAddr");
									}
								}

							} else {
								compareReceiverAddress(order, oldOrder, attrs, orderChangeInfo);
								compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
							}
						} else {
							// exception midend
							throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y1020N1020_MIDEND);
						}
					}
				} else if (!"www.yaodian100.com".equals(order.getDomainSrc())
						&& ("00".equals(order.getOrderSt()) || "05".equals(order.getOrderSt()))) {// 不是主站的，订单状态 '00'或'05' 允许修改地址

					if ((!attrs.get("zipCode").toString().equals(oldOrder.getReceiverZip()))
							|| (!attrs.get("province").toString().equals(oldOrder.getReceiverProvince()))
							|| (!attrs.get("city").toString().equals(oldOrder.getReceiverCity()))
							|| (!attrs.get("district").toString().equals(oldOrder.getReceiverArea()))
							|| (!attrs.get("addr").toString().equals(oldOrder.getReceiverAddr()))) {
						order.setReceiverZip(attrs.get("zipCode").toString());
						order.setReceiverProvince(attrs.get("province").toString());
						order.setReceiverCity(attrs.get("city").toString());
						order.setReceiverArea(attrs.get("district").toString());
						order.setReceiverAddr(attrs.get("addr").toString());
						orderChangeInfo.add("receiverAddr");
					}
					compareReceiverNameMobilePhone(order, oldOrder, attrs, orderChangeInfo);
					compareInvoiceTpandInvoiceTitle(order, oldOrder, attrs, orderChangeInfo);
				} else {
					throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y1020N1020);
				}
			}
			if (orderChangeInfo.size() > 0) {
				String version = deliveryRuleService.findAddressVersion();
				order.setVersion(version);
				if (false == validAddressDataNew(order)) {
					throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_ADDRESS_Y1020N1020);
				}
				this.update(order);
				// 发出修改订单通知信(手机/邮箱会员）&手机会员发短信
				sendOrderModifyMail("orderModifyAddress", order);
				logService.save(this.getClass().getName(), "chgRecvInfo", oldOrder);
			}
			return orderChangeInfo;
		}
	}

	public void compareInvoiceTpandInvoiceTitle(Orders order, Orders oldOrder, Map<String, Object> attrs,
			ArrayList<String> orderChangeInfo) {
		if (null != attrs.get("invotype")) {
			if (!attrs.get("invotype").toString().equals(oldOrder.getInvoiceTp())) {
				// 发票讯息
				order.setInvoiceTp(attrs.get("invotype").toString());
				if ("02".equals(attrs.get("invotype").toString())) {
					order.setInvoiceTitle(attrs.get("invoTitle").toString());
				} else {
					order.setInvoiceTitle("");
				}
				orderChangeInfo.add("invotype");
			}
		}
	}

	public void compareReceiverNameMobilePhone(Orders order, Orders oldOrder, Map<String, Object> attrs,
			ArrayList<String> orderChangeInfo) {
		if (!attrs.get("contactName").toString().equals(oldOrder.getReceiverName())) {
			order.setReceiverName(attrs.get("contactName").toString());
			orderChangeInfo.add("receiverName");
		}

		if (!attrs.get("mobile").toString().equals(oldOrder.getReceiverMobile())) {
			order.setReceiverMobile(attrs.get("mobile").toString());
			orderChangeInfo.add("receiverMobile");
		}

		if ((!attrs.get("areaCode").toString().trim().equals(
				StringUtils.defaultString(oldOrder.getReceiverPhoneArea()).trim()))
				|| (!attrs.get("phone").toString().trim().equals(StringUtils.defaultString(oldOrder.getReceiverPhone()).trim()))
				|| (!attrs.get("extension").toString().trim().equals(
						StringUtils.defaultString(oldOrder.getReceiverExt()).trim()))) {
			order.setReceiverPhoneArea(attrs.get("areaCode").toString().trim());
			order.setReceiverPhone(attrs.get("phone").toString().trim());
			order.setReceiverExt(attrs.get("extension").toString().trim());
			orderChangeInfo.add("receiverPhone");
		}
	}

	public void compareReceiverAddress(Orders order, Orders oldOrder, Map<String, Object> attrs,
			ArrayList<String> orderChangeInfo) {
		if ((!attrs.get("zipCode").toString().equals(oldOrder.getReceiverZip()))
				|| (!attrs.get("province").toString().equals(oldOrder.getReceiverProvince()))
				|| (!attrs.get("city").toString().equals(oldOrder.getReceiverCity()))
				|| (!attrs.get("district").toString().equals(oldOrder.getReceiverArea()))
				|| (!attrs.get("addr").toString().equals(oldOrder.getReceiverAddr()))) {
			order.setReceiverZip(attrs.get("zipCode").toString());
			order.setReceiverProvince(attrs.get("province").toString());
			order.setReceiverCity(attrs.get("city").toString());
			order.setReceiverArea(attrs.get("district").toString());
			order.setReceiverAddr(attrs.get("addr").toString());
			orderChangeInfo.add("receiverAddr");
		}

		if (!attrs.get("province").toString().equals(oldOrder.getReceiverProvince())) {
			// 运费重新计算(要用訂單的商品總額去計算)
			BigDecimal newShipFare = addressService.getFreight(attrs.get("province").toString().trim(), oldOrder
					.getTotalWeight(), oldOrder.getTotalPrice(), oldOrder.getDiscount());
			order.setMustPay(oldOrder.getMustPay().subtract(oldOrder.getShipfare()).add(newShipFare));
			order.setShipfare(newShipFare);
			orderChangeInfo.add("shipfare");
			if (order.getGiftcardBalance().floatValue() > 0) {
				order = orderService.calcOrderProduct(order);// 重新計算禮品卡
			}
			update(order);
			for (String o : StringUtils.split(order.getJoinOrders(), ",")) {
				if (!order.getOrderId().equals(o)) {
					order = get(o);
				}
				order.setJoinMustPay(order.getJoinMustPay().subtract(oldOrder.getShipfare()).add(newShipFare));
				order = orderService.calcOrderProduct(order);// 重新計算禮品卡
				update(order);
			}
		}

	}

	@Transactional(readOnly = false)
	public Orders updateShipfare(String orderId, String newShipfare) {
		Orders order = this.get(orderId);
		if (null != order) {
			if ("00".equals(order.getOrderSt()) || "10".equals(order.getOrderSt())) {
				Orders oldOrder = new Orders();
				try {
					oldOrder = (Orders) BeanUtils.cloneBean(order);
				} catch (Exception e) {
					logger.error("updateShipfare_cloneBean Error:{}", order.getOrderId());
				}
				BigDecimal diffShipfare = order.getShipfare().subtract(new BigDecimal(newShipfare));
				order.setShipfare(new BigDecimal(newShipfare));
				order.setMustPay(order.getMustPay().subtract(diffShipfare));
				order = orderService.calcOrderProduct(order);// 重新計算禮品卡
				order = this.update(order);
				logService.save(this.getClass().getName(), "chgShipfare", oldOrder);
				for (String o : StringUtils.split(order.getJoinOrders(), ",")) {
					order = get(o);
					order.setJoinMustPay(order.getJoinMustPay().subtract(diffShipfare));
					update(order);
				}
			} else {
				throw new CoreException(OrderModifyService.ERROR_ORDER_MODIFY_SHIPFARE_NOO10);
			}
		} else {
			throw new CoreException(OrderModifyService.ERROR_ORDER_ORDER_NOT_EXISTS);
		}

		return order;
	}

	@Transactional(readOnly = false)
	public boolean validAddressDataNew(Orders order) {

		// 如果找不到版本編號,表示省市區不在deliveryRule中
		String verifyOrder = deliveryRuleService.findAddressVersion(order);
		if (StringUtils.isBlank(verifyOrder)) {
			return false;
		} else {
			ViewDeliveryRule viewDeliveryRule = deliveryRuleService.canUseCodByOrderId(order.getOrderId());
			if ("30".equals(order.getPaymentTp()) && "N".equals(viewDeliveryRule.getIsCod())) {
				return false;
			}
			if ("60".equals(order.getPaymentTp()) && "N".equals(viewDeliveryRule.getIsPos())) {
				return false;
			}
			return true;
		}
	}
}
